/*
 * Listener.java
 * iRoomMonitor1.0
 * 10/26/10
 */
package RoomNanny.SpotListener;

import com.sun.spot.io.j2me.radiogram.*;
import java.text.DateFormat;
import java.util.*;
import javax.microedition.io.*;

/**
 * This is a host application for RoomNanny's Java SunSPOTs. This Listener class
 * simply listens over a radio channel for incoming data from a SunSPOT, then
 * pushes that data to a remote database.
 *
 * To build this in ant without a physical basestation, run this command:
 * ant host-run -Dbasestation.shared=true -Dbasestation.not.required=true
 *
 * @author Joe Granville
 */
public class Listener {

    // Broadcast port on which we listen for sensor samples
    private static final int HOST_PORT = 67;
    
    /**
     * This method runs the basestation, as it listens for Sunspots sending
     * data on to be put into the database. This method collects this data,
     * formats it, and sends it on to be push into the database.
     */
    private void run() throws Exception {

        RadiogramConnection inConnection;   // incoming radiogram connection
        Datagram dg;                        // datagram for incoming data
        DateFormat fmt = DateFormat.getTimeInstance();
        DBConnector db = new DBConnector();

        try {
            // Open up a server-side broadcast radiogram connection
            // to listen for sensor readings being sent by different SPOTs
            inConnection = (RadiogramConnection) Connector.open("radiogram://:"
                    + HOST_PORT);
            dg = inConnection.newDatagram(inConnection.getMaximumLength());
        } catch (Exception e) {
            System.err.println("setUp caught " + e.getMessage());
            throw e;
        }
        db.connect("cs340.pugetsound.edu/RoomNanny");

        // Main data collection loop
        while (true) {
            String addr = null;
            long time = 0;
            int spotIDReading = -1;
            double tempReading = 0;
            boolean lightReading = false;
            int doorOpening = 3;
            int powerPct = 0;

            try {
                // Read sensor sample received over the radio
                inConnection.receive(dg);
                addr = dg.getAddress(); // read sender's address

                if (dg.readShort() == 1) {
                    // This must be a request for an ID!
                    int newID = db.register(addr);

                    // new outgoing datagram
                    RadiogramConnection outConnection =
                            (RadiogramConnection) Connector.open("radiogram://broadcast:" + HOST_PORT);
                    Datagram outDG = outConnection.newDatagram(inConnection.getMaximumLength());

                    System.out.println("Assigning spot " + addr + " to ID "
                                       + newID);

                    outDG.writeUTF(addr);
                    outDG.writeInt(newID);
                    outConnection.send(outDG);
                    outConnection.close();
                } else {
                    // Get the sensor's readings
                    spotIDReading = dg.readInt();
                    time = dg.readLong(); // read time of the reading
                    tempReading = dg.readDouble(); // read the sensor value
                    lightReading = dg.readBoolean();
                    doorOpening = dg.readInt();
                    powerPct = dg.readInt();
                    System.out.println(fmt.format(new Date(time)) + " from: "
                            + addr + " " + spotIDReading + " temp = " + tempReading
                            + " l"
                            + "ight = " + lightReading
                            + " door = "+doorOpening
                            + " power = " + powerPct);
                                    // Get data to the database
                    System.out.println("Sending data...");
                    db.push(time, addr, spotIDReading, tempReading, 
                            doorOpening, lightReading, powerPct);
                }
            } catch (Exception e) {
                System.err.println("Caught " + e + " while reading sensor samples.");
                throw e;
            }
        }

    }

    /**
     * Start up the host application.
     *
     * @param args any command line arguments
     */
    public static void main(String[] args) throws Exception {
        Listener app = new Listener();
        app.run();
    }
}
